#    Copyright 2008, 2009 Tri-County Electric Cooperative, St. Matthews, South Carolina
#    This file is part of COOPGIS.
#    COOPGIS is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    COOPGIS is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with COOPGIS.  If not, see <http://www.gnu.org/licenses/>.

import os
import datetime
FTPFileName='/opt/coopgis/fromgps/anonymousftproot_OtherReadOnly/incomingftpallpermissions/Locations.csv'
import shutil

#************************BEGIN Add Include Files to Path************************
import sys
NeededPaths=['/opt/coopgis/djangoproject/include', '/opt/coopgis/djangoproject']
for path in NeededPaths:
    if(not path in sys.path):
        sys.path.append(path)
#************************END   Add Include Files to Path************************
from django.contrib.gis.geos import *
import os, time, psycopg2, datetime
#********************Setup psycopg2 and django section********************
PathDjangoRoot="/opt/coopgis/"
if(not PathDjangoRoot in sys.path):
    sys.path.append(PathDjangoRoot)
import djangoproject
from djangoproject.models import *
#********************Setup psycopg2 and django section********************
import COOPGIS_Ajax, COOPGIS_GPS, COOPGIS_Misc, COOPGIS_ReportLab, COOPGIS_String, COOPGIS_Update, COOPGIS_FormMisc
from django.template import Context, loader
from django.http import HttpResponse
from django import forms
import os
import datetime
import djangoproject.settings

def BuildGroundRodTestForm(DefaultMap):
    NumberOfGroundRodTestsListedOnForm=25
    Dict={}
    #Build Map Choices List
    MapChoices=[]
    MapChoices.append([DefaultMap.id, str(DefaultMap.Name)[:30]])
    Maps=Map.objects.all()
    for i in Maps:
        if(not i == DefaultMap):
            MapChoices.append([i.id, str(i.Name)[:30]])
    #Create the GroundRodTestCompanyChoices
    GroundRodTestCompanyChoices=[]
    GroundRodTestCompanies=Company.objects.all().filter(GroundRodTestIndicator=True).order_by('Name')
    GroundRodTestCompanyChoices.append(['-1', 'None'])
    for i in GroundRodTestCompanies:
        GroundRodTestCompanyChoices.append([i.id, str(i)])
    for GroundRodTest in range(0, NumberOfGroundRodTestsListedOnForm):
        Dict['UpdateIndicator' + str(GroundRodTest)]=forms.BooleanField()
        Dict['GroundRodTestid' + str(GroundRodTest)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'4', 'READONLY':'True'}))
        Dict['GroundRodTestCompany' + str(GroundRodTest)]=forms.ChoiceField(GroundRodTestCompanyChoices, required=False)
        Dict['GroundRodTestDate' + str(GroundRodTest)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'7'}))    
        Dict['GroundRodTestResistanceReading' + str(GroundRodTest)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'7'}))  
        Dict['GroundRodTestGroundRodNumber' + str(GroundRodTest)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'7'}))  
        Dict['GroundRodTestWorkOrderNumber' + str(GroundRodTest)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'7'}))  
        Dict['GroundRodTestDescription' + str(GroundRodTest)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'7'}))  
        Dict['GroundRodTestSetupIndicator' + str(GroundRodTest)]=forms.BooleanField()
        Dict['GroundRodTestInspectionPersonName' + str(GroundRodTest)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'7'}))  
        Dict['GroundRodTestSubstationName' + str(GroundRodTest)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'7'}))  
        Dict['DeleteIndicator' + str(GroundRodTest)]=forms.BooleanField()
    Dict['Map']=forms.ChoiceField(MapChoices, required=False)
    Dict['SelectStationTagNumber']=forms.CharField(max_length = 25, required=False, widget=forms.TextInput(attrs={'size':'4'}))
    Dict['SelectStationid']=forms.CharField(max_length = 25, required=False, widget=forms.TextInput(attrs={'size':'4'}))
    Dict['SelectGPSIndicator']=forms.BooleanField()
    return Dict


def BuildGroundRodTestReportForm():
    NumberOfGroundRodTestsListedOnForm=8
    Dict={}
    #Create the GroundRodTestCompanyChoices
    GroundRodTestCompanyChoices=[]
    GroundRodTestCompanies=Company.objects.all().filter(GroundRodTestIndicator=True).order_by('Name')
    GroundRodTestCompanyChoices.append(['-1', 'None'])
    for i in GroundRodTestCompanies:
        GroundRodTestCompanyChoices.append([i.id, str(i)])
    Dict['GroundRodTestCompany']=forms.ChoiceField(GroundRodTestCompanyChoices, required=False)
    Dict['GroundRodTestStartCreateDate']=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'7'}))
    Dict['GroundRodTestEndCreateDate']=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'7'}))
    Dict['GroundRodTestStartTreatmentDate']=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'7'}))
    Dict['GroundRodTestEndTreatmentDate']=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'7'}))
    Dict['GroundRodTestResistanceGreaterThanX']=forms.FloatField(required=False, widget=forms.TextInput(attrs={'size':'7'}))
    Dict['GroundRodTestDetailedIndicator']=forms.BooleanField()
    Dict['GroundRodTestVeryDetailedIndicator']=forms.BooleanField()
    return Dict


def ProcessGroundRodTest(form, GroundRodTestFormNumber, SelectionStation, UserName, ProcessQuickLine=False):
    try:
        GroundRodTestid=int(form.data['GroundRodTestid' + str(GroundRodTestFormNumber)])
        groundRodTest=compatibleunit.GroundRodTest.objects.filter(id=GroundRodTestid)[0]
    except:
        GroundRodTestid='New'
    if(ProcessQuickLine):  #Always create a new ground rod for the quick line
        GroundRodTestid='New'
    company=COOPGIS_FormMisc.FormGetObjectFromid(form, 'GroundRodTestCompany' + str(GroundRodTestFormNumber), Company)
    GroundRodTestDate=COOPGIS_FormMisc.FormGetDateTime(form, 'GroundRodTestDate' + str(GroundRodTestFormNumber))
    if(not GroundRodTestDate):
        GroundRodTestDate = datetime.datetime.now()
    GroundRodNumber=COOPGIS_FormMisc.FormGetInteger(form, 'GroundRodTestGroundRodNumber' + str(GroundRodTestFormNumber))
    WorkOrderNumber=COOPGIS_FormMisc.FormGetString(form, 'GroundRodTestWorkOrderNumber' + str(GroundRodTestFormNumber))
    InspectionPersonName=COOPGIS_FormMisc.FormGetString(form, 'GroundRodTestInspectionPersonName' + str(GroundRodTestFormNumber))
    SubstationName=COOPGIS_FormMisc.FormGetString(form, 'GroundRodTestSubstationName' + str(GroundRodTestFormNumber))
    SetupIndicator=COOPGIS_FormMisc.FormGetBoolean(form, 'GroundRodTestSetupIndicator' + str(GroundRodTestFormNumber))
    ResistanceReading=COOPGIS_FormMisc.FormGetFloat(form, 'GroundRodTestResistanceReading' + str(GroundRodTestFormNumber))
    Description=COOPGIS_FormMisc.FormGetString(form, 'GroundRodTestDescription' + str(GroundRodTestFormNumber))
    UpdateIndicator=COOPGIS_FormMisc.FormGetBoolean(form, 'UpdateIndicator' + str(GroundRodTestFormNumber))
    DeleteIndicator=COOPGIS_FormMisc.FormGetBoolean(form, 'DeleteIndicator' + str(GroundRodTestFormNumber))
    #raise(Exception('Here'))
    if(not SelectionStation):
        pass #Do not attempt any actions if a station is not selected
    elif(UpdateIndicator and company):
        if(GroundRodTestid == 'New'):  #Create a New GroundRodTest 
            command=Command()
            command=command.Create(Name='CreateGroundRodTest', StartPoint=SelectionStation.Point, CompanyName=company.Name, GroundRodTestDate=GroundRodTestDate,
                                   CommandUserName=UserName, WorkOrderNumber=WorkOrderNumber, Description=Description, SetupIndicator=SetupIndicator, 
                                   ResistanceReading=ResistanceReading, GroundRodNumber=GroundRodNumber,
                                   InspectionPersonName=InspectionPersonName, SubstationName=SubstationName)
            command.save()
            groundRodTest=command.Process()
        elif(GroundRodTestid):  #GroundRodTest Already Exists, so Edit it
            GroundRodTestToEdit=groundRodTest
            Age=datetime.datetime.now() - GroundRodTestToEdit.CreateDateTime
            if(Age.days > 185):
                return #Do not allow editing of Ground Rod Tests older than ~6 months through the form interface
            if(GroundRodTestToEdit.ResidesOnServerIndicator):
                command=Command()
                command=command.Create(Name='EditGroundRodTest', Objectid=GroundRodTestToEdit.id, CompanyName=company.Name, GroundRodTestDate=GroundRodTestDate,
                                   CommandUserName=UserName, WorkOrderNumber=WorkOrderNumber, Description=Description, SetupIndicator=SetupIndicator, 
                                   ResistanceReading=ResistanceReading, GroundRodNumber=GroundRodNumber,
                                   InspectionPersonName=InspectionPersonName, SubstationName=SubstationName)
                command.save()
                command.Process()
            else:
                command=Command.objects.filter(id=GroundRodTestToEdit.CreateCommand.id)[0]
                command.Set('CompanyName', company.Name)
                command.CommandUserName=UserName
                command.StartPoint=SelectionStation.Point
                command.Set('GroundRodTestDate', GroundRodTestDate)
                command.Set('WorkOrderNumber', WorkOrderNumber)
                command.Set('Description', Description)
                command.Set('SetupIndicator', SetupIndicator)
                command.Set('InspectionPersonName', InspectionPersonName)
                command.Set('WorkOrderNumber', WorkOrderNumber)
                command.Set('GroundRodNumber', GroundRodNumber)
                command.Set('ResistanceReading', ResistanceReading)
                command.Set('SubstationName', SubstationName)
                command.save()
                GroundRodTestToEdit.Company=company
                GroundRodTestToEdit.GroundRodTestDate=GroundRodTestDate
                GroundRodTestToEdit.CommandUserName=UserName
                GroundRodTestToEdit.InspectionPersonName=InspectionPersonName
                GroundRodTestToEdit.WorkOrderNumber=WorkOrderNumber
                GroundRodTestToEdit.SubstationName=SubstationName
                GroundRodTestToEdit.Description=Description
                GroundRodTestToEdit.GroundRodNumber=GroundRodNumber
                GroundRodTestToEdit.ResistanceReading=ResistanceReading
                GroundRodTestToEdit.SetupIndicator=SetupIndicator
                GroundRodTestToEdit.save()
    elif(DeleteIndicator and not GroundRodTestid == 'New'):  #Delete an Existing Assembly, cannot delete a new one
        DeleteGroundRodTest(GroundRodTestid, UserName)

def DeleteGroundRodTest(GroundRodTestid, UserName):
    """Returns the Order of the command deleted if deleting a command was necessary, otherwise returns 0 if successful"""
    GroundRodTestToDelete=GroundRodTest.objects.filter(id=GroundRodTestid)[0]
    if(GroundRodTestToDelete.ResidesOnServerIndicator):   #Create the appropriate Command if on the server
        command=Command()
        command=command.Create(Name='DeleteGroundRodTest', GroundRodTestid=GroundRodTestid, CommandUserName=UserName)
        command=command.Process()
        return 0
    else:  #Delete the appropriate commands that would create it on the server if it only exists on the client
        commandid=int(str(GroundRodTestToDelete.CreateCommand.id)) #int(str()) to force the query to execute before the deletion
        GroundRodTestToDelete.delete()
        command=Command.objects.filter(id__exact=commandid)
        command[0].delete()
        return 0


def ProcessGroundRodTestReport(form):
    try:
        Companyid=int(form.data['GroundRodTestCompany'])
        company=Company.objects.filter(id__exact=Companyid)[0]
        CompanyName=company.Name
    except:
        company=None
        CompanyName=''
    try:
        GroundRodTestStartCreateDate=COOPGIS_String.StringToDate(form.data['GroundRodTestStartCreateDate'])
    except:
        GroundRodTestStartCreateDate=None
    try:
        GroundRodTestEndCreateDate=COOPGIS_String.StringToDate(form.data['GroundRodTestEndCreateDate'])
    except:
        GroundRodTestEndCreateDate=None
    try:
        GroundRodTestStartTreatmentDate=COOPGIS_String.StringToDate(form.data['GroundRodTestStartTreatmentDate'])
    except:
        GroundRodTestStartTreatmentDate=None
    try:
        GroundRodTestEndTreatmentDate=COOPGIS_String.StringToDate(form.data['GroundRodTestEndTreatmentDate'])
    except:
        GroundRodTestEndTreatmentDate=None
    try:
        GroundRodTestResistanceGreaterThanX=float(form.data['GroundRodTestResistanceGreaterThanX'])
    except:
        GroundRodTestResistanceGreaterThanX=None
    try:
        GroundRodTestDetailedIndicator=bool(form.data['GroundRodTestDetailedIndicator'] == 'on')
    except:
        GroundRodTestDetailedIndicator=False
    try:
        GroundRodTestVeryDetailedIndicator=bool(form.data['GroundRodTestVeryDetailedIndicator'] == 'on')
    except:
        GroundRodTestVeryDetailedIndicator=False

    GroundRodTests=djangoproject.models.compatibleunit.GroundRodTest.objects.all().order_by('GroundRodNumber')
    if(company):
        GroundRodTests=GroundRodTests.filter(Company=company)
    if(GroundRodTestStartCreateDate):
        GroundRodTests=GroundRodTests.exclude(CreateDateTime__lte=GroundRodTestStartCreateDate)
    if(GroundRodTestEndCreateDate):
        GroundRodTests=GroundRodTests.exclude(CreateDateTime__gte=GroundRodTestEndCreateDate)
    if(GroundRodTestStartTreatmentDate):
        GroundRodTests=GroundRodTests.exclude(GroundRodTestDate__lte=GroundRodTestStartTreatmentDate)
    if(GroundRodTestEndTreatmentDate):
        GroundRodTests=GroundRodTests.exclude(GroundRodTestDate__gte=GroundRodTestEndTreatmentDate)
    if(GroundRodTestResistanceGreaterThanX):
        GroundRodTests=GroundRodTests.exclude(ResistanceReading__lte=GroundRodTestResistanceGreaterThanX)
    Details=[]
    TempDetails=[]         
    if(GroundRodTestDetailedIndicator and not GroundRodTestVeryDetailedIndicator):
        Headings=['Station ID','Number of GroundRods Driven', 'Initial Resistance', 'Highest', 'Lowest', 'Final', 'Change']
        Stations={}
        for groundRodTest in GroundRodTests:
            Stations[str(groundRodTest.StationIdentifier)]=[]
        for groundRodTest in GroundRodTests:
            Stations[str(groundRodTest.StationIdentifier)].append(groundRodTest)

        for station in Stations.keys():
            initialResistanceReading= None
            highestResistanceReading= None
            lowestResistanceReading= 100000000 #no number can be less than None
            for groundRodTest in Stations[station]:
                if (groundRodTest.GroundRodNumber == 1):
                    firstGroundRod = groundRodTest
                if (groundRodTest.ResistanceReading > highestResistanceReading):
                    highestResistanceReading= groundRodTest.ResistanceReading
                if (groundRodTest.ResistanceReading < lowestResistanceReading):
                    lowestResistanceReading= groundRodTest.ResistanceReading  

            Row=[]
            Row.append(groundRodTest.StationIdentifier)
            Row.append(groundRodTest.GroundRodNumber)
            Row.append(firstGroundRod.ResistanceReading)
            Row.append(highestResistanceReading)
            Row.append(lowestResistanceReading)
            Row.append(groundRodTest.ResistanceReading)
            Row.append((groundRodTest.ResistanceReading) - (firstGroundRod.ResistanceReading))
            TempDetails.append(Row)
        TempDetails.sort()
        for row in TempDetails:
            Details.append(row)

    elif(GroundRodTestVeryDetailedIndicator):
        
        Headings=[]
        Headings.append('Station ID')
        Headings.append('Pole Tag')
        Headings.append('Original Test')
        Headings.append('Setup Indicator')

        Stations={}
        for groundRodTest in GroundRodTests:
            Stations[str(groundRodTest.StationIdentifier)]=[]
        for groundRodTest in GroundRodTests:
            Stations[str(groundRodTest.StationIdentifier)].append(groundRodTest)
     #   raise(Exception(Stations['105415']))
        maxCount=0
        for station in Stations.keys():    
            firstTime=True
            currCount=0
            for groundRodTest in Stations[station]:
                currCount+=1
                if currCount > maxCount:
                    maxCount = currCount
                if (firstTime):
                    Row=[]
                    Row.append(groundRodTest.StationIdentifier)
                    Poles=Assembly.objects.filter(Station=station).filter(CompatibleUnit__PoleIndicator=True)
                    if Poles:
                        Row.append(Poles[0].TagNumber)
                    else:
                        Row.append('No Pole')
                    Row.append(groundRodTest.ResistanceReading)
                    Row.append(groundRodTest.SetupIndicator)
                    firstTime=False
                else:
                    Row.append(groundRodTest.ResistanceReading)
            else:
                while currCount < maxCount:
                    Row.append('')
                    currCount+=1
            
            TempDetails.append(Row)

        TempDetails.sort()
        for row in TempDetails:
            Details.append(row) 
        i=1
        while i < maxCount:
            Headings.append('Rod Test \n' + str(i))
            i+=1


    else:
        Headings=['Total', 'Setups']
        Total= GroundRodTests.count()
        Setups= GroundRodTests.filter(SetupIndicator=True).count()
        Details=[Total, Setups]
    return Headings, Details, bool(GroundRodTestDetailedIndicator or GroundRodTestVeryDetailedIndicator)


def PopulateGroundRodTestFormFields(form, SelectionStation, NumberOfGroundRodTestsListedOnForm):
    if(SelectionStation):
        GroundRodTests=GroundRodTest.objects.filter(StationIdentifier=SelectionStation.id).order_by('GroundRodNumber')
    else:
        GroundRodTests=None
 
    for GroundRodTestFormNumber in range(0, NumberOfGroundRodTestsListedOnForm):
        try:
            if(GroundRodTestFormNumber == 0):
                raise(Exception('0 is the QuickLine, populating with a blank form'))
            form.data['UpdateIndicator' + str(GroundRodTestFormNumber)]=False
            form.data['GroundRodTestid' + str(GroundRodTestFormNumber)]=GroundRodTests[GroundRodTestFormNumber-1].id
            form.data['GroundRodTestCompany' + str(GroundRodTestFormNumber)]=GroundRodTests[GroundRodTestFormNumber-1].Company.id
            form.data['GroundRodTestDate' + str(GroundRodTestFormNumber)]=GroundRodTests[GroundRodTestFormNumber-1].GroundRodTestDate
            form.data['GroundRodTestWorkOrderNumber' + str(GroundRodTestFormNumber)]=GroundRodTests[GroundRodTestFormNumber-1].WorkOrderNumber
            form.data['GroundRodTestDescription' + str(GroundRodTestFormNumber)]=GroundRodTests[GroundRodTestFormNumber-1].Description
            form.data['GroundRodTestSetupIndicator' + str(GroundRodTestFormNumber)]=GroundRodTests[GroundRodTestFormNumber-1].SetupIndicator
            form.data['GroundRodTestResistanceReading' + str(GroundRodTestFormNumber)]=GroundRodTests[GroundRodTestFormNumber-1].ResistanceReading
            form.data['GroundRodTestGroundRodNumber' + str(GroundRodTestFormNumber)]=GroundRodTests[GroundRodTestFormNumber-1].GroundRodNumber
            form.data['GroundRodTestInspectionPersonName' + str(GroundRodTestFormNumber)]=GroundRodTests[GroundRodTestFormNumber-1].InspectionPersonName
            form.data['GroundRodTestSubstationName' + str(GroundRodTestFormNumber)]=GroundRodTests[GroundRodTestFormNumber-1].SubstationName
            form.data['DeleteIndicator' + str(GroundRodTestFormNumber)]=False  
        except:
            form.data['UpdateIndicator' + str(GroundRodTestFormNumber)]=False
            form.data['GroundRodTestid' + str(GroundRodTestFormNumber)]=''
            form.data['GroundRodTestCompany' + str(GroundRodTestFormNumber)]=-1
            form.data['GroundRodTestDate' + str(GroundRodTestFormNumber)]=''    
            form.data['GroundRodTestWorkOrderNumber' + str(GroundRodTestFormNumber)]=''
            form.data['GroundRodTestDescription' + str(GroundRodTestFormNumber)]=''
            form.data['GroundRodTestSetupIndicator' + str(GroundRodTestFormNumber)]=False
            form.data['GroundRodTestResistanceReading' + str(GroundRodTestFormNumber)]=''
            form.data['GroundRodTestGroundRodNumber' + str(GroundRodTestFormNumber)]=''
            form.data['GroundRodTestInspectionPersonName' + str(GroundRodTestFormNumber)]=''
            form.data['GroundRodTestSubstationName' + str(GroundRodTestFormNumber)]=''
            form.data['DeleteIndicator' + str(GroundRodTestFormNumber)]=False  






